<?php

namespace app\admin\controller;

use app\common\controller\Backend;
use think\facade\Db;
use Throwable;

/**
 * 医务人员信息管理
 */
class MedicalStaff extends Backend
{
    /**
     * MedicalStaff模型对象
     * @var object
     * @phpstan-var \app\admin\model\MedicalStaff
     */
    protected object $model;
    protected bool|string|int $dataLimit = false;

    protected array|string $preExcludeFields = ['id', 'staff_number', 'created_at', 'updated_at', 'external_id'];

    protected string|array $quickSearchField = ['id', 'name'];

    public function initialize(): void
    {
        parent::initialize();
        $this->model = new \app\admin\model\MedicalStaff();
    }


    /**
     * 若需重写查看、编辑、删除等方法，请复制 @see \app\admin\library\traits\Backend 中对应的方法至此进行重写
     */


    /**
     * 查看
     * @throws Throwable
     */
    public function index(): void
    {
        if ($this->request->param('select')) {
            $this->select();
        }

        list($where, $alias, $limit, $order) = $this->queryBuilder();
        $where[] = $this->buildStoreWhere('store_medical_staff_relation.store_id');
        $res = $this->model
            ->field('medical_staff.*')
            ->withJoin($this->withJoinTable, $this->withJoinType)
            ->leftJoin('store_medical_staff_relation', 'medical_staff.id = store_medical_staff_relation.medical_staff_id')
            ->alias($alias)
            ->where($where)
            ->order($order)
            ->paginate($limit);
        $res->each(function ($item) {
            $item->append(['role_names', 'role_ids']);
        });
        $this->success('', [
            'list'   => $res->items(),
            'total'  => $res->total(),
            'remark' => get_route_remark(),
        ]);
    }

    public function select(): void
    {
        $medical_role_id = env('MEDICAL_ROLE_ID', '');
        if (!$medical_role_id) {
            $this->error('医师角色ID未配置');
        }
        list($where, $alias, $limit, $order) = $this->queryBuilder();
        $where[] = $this->buildStoreWhere('store_medical_staff_relation.store_id');
        $where[] = ['medical_staff_role.role_id', '=', $medical_role_id];
        $res = $this->model
            ->field('medical_staff.*')
            ->Join('medical_staff_role', 'medical_staff.id = medical_staff_role.medical_staff_id and medical_staff_role.role_id = ' . (int)$medical_role_id)
            ->leftJoin('store_medical_staff_relation', 'medical_staff.id = store_medical_staff_relation.medical_staff_id')
            ->withJoin($this->withJoinTable, $this->withJoinType)
            ->alias($alias)
            ->where($where)
            ->order($order)
            ->paginate($limit);

        $this->success('', [
            'list'   => $res->items(),
            'total'  => $res->total(),
            'remark' => get_route_remark(),
        ]);
    }
    /**
     * 添加
     */
    public function add(): void
    {
        $this->setBeforeValidateFun(function ($data): array {
            $data['store_id'] = $this->request->store_id; // 手动设置 store_id 用于验证
            return $data;
        })->setAfterValidateFun(function ($data): array {
            unset($data['store_id']); //是多对多，存在关联表中，所以需要删除store_id
            return $data;
        })->setAfterExecFun(function ($newData): mixed {
            // 关联门店
            Db::name('store_medical_staff_relation')->insert([
                'store_id' => $this->request->store_id,
                'medical_staff_id' => $this->model->id,
            ]);
            // 处理角色关联
            $roleIds  = $newData['role_ids'] ?? [];
            if (is_array($roleIds) && !empty($roleIds)) {
                $insert = [];
                foreach ($roleIds as $rid) {
                    $insert[] = ['medical_staff_id' => $this->model->id, 'role_id' => (int)$rid];
                }
                if (!empty($insert)) {
                    Db::name('medical_staff_role')->insertAll($insert);
                }
            }
            return true;
        });
        parent::add();
    }

    /**
     * 编辑
     */
    public function edit(): void
    {
        $this->setBeforeValidateFun(function ($newData, $oldData): array {
            $newData['store_id'] = $this->request->store_id;
            return $newData;
        })->setAfterValidateFun(function ($newData, $oldData): array {
            unset($newData['store_id']); //是多对多，存在关联表中，验证完了删除store_id
            Db::name('store_medical_staff_relation')->where('store_id', $this->request->store_id)->where('medical_staff_id', $oldData['id'])->delete();
            return $newData;
        })->setAfterExecFun(function ($newData, $oldData): mixed {

            $id = $oldData['id'];
            Db::name('store_medical_staff_relation')->insert([
                'store_id' => $this->request->store_id,
                'medical_staff_id' => $id,
            ]);
            // 清空原有关联
            Db::name('medical_staff_role')->where('medical_staff_id', $id)->delete();
            // 重新写入
            $roleIds = $newData['role_ids'] ?? [];
            if (!empty($roleIds)) {
                $insert = [];
                foreach ($roleIds as $rid) {
                    $insert[] = ['medical_staff_id' => $id, 'role_id' => (int)$rid];
                }
                if (!empty($insert)) {
                    Db::name('medical_staff_role')->insertAll($insert);
                }
            }
            return true;
        });
        $this->setEditedFun(function ($row): mixed {
            $row->append(['role_ids']);
            return $row;
        });
        parent::edit();
    }

    public function del(): void
    {
        $this->setAfterExecFun(function ($ids, $oldData): mixed {
            Db::name('store_medical_staff_relation')
                ->where('store_id', $this->request->store_id)
                ->whereIn('medical_staff_id', $ids)
                ->delete();
            Db::name('medical_staff_role')
                ->whereIn('medical_staff_id', $ids)
                ->delete();
            return true;
        });
        parent::del();
    }
}
